package com.gitee.wsl.platform.concurrent

import kotlinx.coroutines.CloseableCoroutineDispatcher
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Runnable
import kotlin.coroutines.CoroutineContext

internal actual class InternalThreadId{
    /**
     * Name of the thread
     */
     var name: String = "Main Thread"
        set(_) = Unit

    /**
     * Always `true` since on JavaScript there is only one thread.
     */
     val isMainThread: Boolean = true

    override fun equals(other: Any?): Boolean = other is InternalThreadId

    override fun hashCode(): Int {
        return this::class.hashCode()
    }

    //override fun hashCode(): Int = this::class.js.hashCode()
}

internal actual class InternalThread {
    actual companion object {
        actual fun getId(): InternalThreadId = InternalThreadId()

        actual fun sleepMs(millis: Int) {
        }
    }
}

/**
 * Runs the provided [block] on the main thread.
 * Since JavaScript does not have any threading, this will just run [block]
 * @param block the code to run on the main thread.
 */
actual fun runOnMain(block: () -> Unit) {
    block()
}

/**
 * Creates a coroutine execution context using a single thread.
 * Since JavaScript does not have threading support, this will just return [Dispatchers.Default]
 * @param name The name of the thread to be created.
 */
@OptIn(ExperimentalCoroutinesApi::class)
actual fun singleThreadDispatcher(name: String): CloseableCoroutineDispatcher = CoroutineDispatcherWrapper(Dispatchers.Default)

/**
 * Creates a coroutine execution context using a thread pool.
 * Since JavaScript does not have threading support, this will just return [Dispatchers.Default]
 * @param numberOfThreads The number of the threads that the thread pool should consist of.
 * @param name The name of the thread pool to be created.
 */
@OptIn(ExperimentalCoroutinesApi::class)
actual fun threadPoolDispatcher(numberOfThreads: UInt, name: String): CloseableCoroutineDispatcher = CoroutineDispatcherWrapper(Dispatchers.Default)

@OptIn(ExperimentalCoroutinesApi::class)
private class CoroutineDispatcherWrapper(private val base: CoroutineDispatcher) : CloseableCoroutineDispatcher() {
    override fun dispatch(context: CoroutineContext, block: Runnable) {
        base.dispatch(context, block)
    }
    override fun close() = Unit
}